package com.ouyunc.gateway.config.oauth.override;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

/**
 * @Author fangzhenxun
 * @Description: 对提取并且封装好的authentication 进行有效期以及其他非法jwt校验
 * @Version V1.0
 **/
@Component
public class IReactiveAuthenticationManager implements ReactiveAuthenticationManager {
    private static Logger log = LoggerFactory.getLogger(IReactiveAuthenticationManager.class);

    @Autowired
    private TokenStore tokenStore;

    /**
     * @Author fangzhenxun
     * @Description 认证处理器，如果不加token进行访问不会走这里，但都会走IServerAuthenticationConverter，  具体看AuthenticationWebFilter
     * 0,直接访问网关服务中的接口，访问网关下游服务进行情况分析与处理
     * 1,没有token
     * 2,有token，
     *   2.1，token失效，或非法token
     *   2.2，token合法
     *      2.2.1，有权限访问接口数据
     *      2.2.2，没有权限访问接口数据
     * @param authenticationToken
     * @return reactor.core.publisher.Mono<org.springframework.security.core.Authentication>
     */
    @Override
    public Mono<Authentication> authenticate(Authentication authenticationToken) {
        // 根据token从缓存中取出凭证
        OAuth2Authentication oAuth2Authentication = tokenStore.readAuthentication((String) authenticationToken.getPrincipal());
        // 解析token
        if (oAuth2Authentication == null) {
            return  Mono.error(new BadCredentialsException("非法Bearer token！"));
        }
        Authentication userAuthentication = oAuth2Authentication.getUserAuthentication();
        // 将用户信息存到上下文中
        return Mono.just(userAuthentication);
    }
}
